package com.tinysand.advert.service.impl;

import com.tinysand.advert.constant.CommonStatus;
import com.tinysand.advert.constant.SystemConstant;
import com.tinysand.advert.entity.AdvertPlan;
import com.tinysand.advert.entity.AdvertUser;
import com.tinysand.advert.exception.AdvertException;
import com.tinysand.advert.repository.PlanRepository;
import com.tinysand.advert.repository.UserRepository;
import com.tinysand.advert.service.AdPlanService;
import com.tinysand.advert.support.AdPlanGetRequest;
import com.tinysand.advert.support.AdPlanRequest;
import com.tinysand.advert.support.AdPlanResponse;
import com.tinysand.advert.utils.CommonUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Optional;

/**
 * 推广计划服务接口实现
 *
 * Created By TINY
 * Create Time 2020/2/21
 **/
@Slf4j
@Service
public class AdPlanServiceImpl implements AdPlanService {

    /* 用户数据持久层对象 */
    private final UserRepository userRepository;

    /* 推广计划持久层对象 */
    private final PlanRepository planRepository;

    public AdPlanServiceImpl(UserRepository userRepository,
                             PlanRepository planRepository) {
        this.userRepository = userRepository;
        this.planRepository = planRepository;
    }

    /**
     * 创建推广计划
     *
     * @param request 创建推广计划的请求数据对象 {@link AdPlanRequest}
     * @return 推广计划创建结果响应对象 {@link AdPlanResponse}
     * @throws AdvertException 业务异常
     */
    @Override
    @Transactional // 写入数据，开启事务
    public AdPlanResponse createAdPlan(AdPlanRequest request)
            throws AdvertException {

        if (!request.createValidate()) {
            throw new AdvertException(SystemConstant.Error.REQUEST_PARAM_ERROR);
        }

        // 要确保关联的用户是存在的
        Optional<AdvertUser> advertUser = userRepository
                .findById(request.getUserId());

        if (!advertUser.isPresent()) {
            throw new AdvertException(SystemConstant.Error.RECORD_NOT_FOUND);
        }

        AdvertPlan oldPlan = planRepository.findByUserIdAndName(
                request.getUserId(), request.getPlanName());

        if (oldPlan != null) {
            throw new AdvertException(SystemConstant.Error.SAME_PLAN_PRESENT);
        }

        AdvertPlan newPlan = planRepository.save(new AdvertPlan(
                request.getUserId(), request.getPlanName(),
                CommonUtils.parseStringDate(request.getStartDate()),
                CommonUtils.parseStringDate(request.getEndDate())
        ));

        return new AdPlanResponse(
                newPlan.getId(), newPlan.getName()
        );
    }

    /**
     * 根据请求获取所有指定的推广计划
     *
     * @param request 获取推广计划的请求对象 {@link AdPlanGetRequest}
     * @return 所有符合的推广计划
     * @throws AdvertException 业务异常
     */
    @Override
    public List<AdvertPlan> getAdPlanByIds(AdPlanGetRequest request)
            throws AdvertException {

        if (!request.validate()) {
            throw new AdvertException(SystemConstant.Error.REQUEST_PARAM_ERROR);
        }

        return planRepository.findAllByIdInAndUserId(
                request.getIds(), request.getUserId());
    }

    /**
     * 更新指定的推广计划数据
     *
     * @param request 更新推广计划的请求对象 {@link AdPlanGetRequest}
     * @return 推广计划更新结果响应对象 {@link AdPlanResponse}
     * @throws AdvertException 业务异常
     */
    @Override
    @Transactional
    public AdPlanResponse updateAdPlan(AdPlanRequest request)
            throws AdvertException {

        if (!request.updateValidate()) {
            throw new AdvertException(SystemConstant.Error.REQUEST_PARAM_ERROR);
        }

        AdvertPlan plan = planRepository.findByIdAndUserId(
                request.getId(), request.getUserId()
        );

        if (null == plan) {
            throw new AdvertException(SystemConstant.Error.RECORD_NOT_FOUND);
        }

        if (null != request.getPlanName()) {
            plan.setName(request.getPlanName());
        }

        if (null != request.getStartDate()) {
            plan.setStartDate(CommonUtils.parseStringDate(request.getStartDate()));
        }

        if (null != request.getEndDate()) {
            plan.setEndDate(CommonUtils.parseStringDate(request.getEndDate()));
        }

        plan.setUpdateTime(new Date());
        plan = planRepository.save(plan);

        return new AdPlanResponse(plan.getId(), plan.getName());
    }

    /**
     * 删除推广计划
     *
     * @param request 删除推广计划的请求对象 {@link AdPlanGetRequest}
     * @throws AdvertException 业务异常
     */
    @Override
    @Transactional
    public void deleteAdPlan(AdPlanRequest request)
            throws AdvertException {

        if (!request.deleteValidate()) {
            throw new AdvertException(SystemConstant.Error.REQUEST_PARAM_ERROR);
        }

        AdvertPlan plan = planRepository.findByIdAndUserId(
                request.getId(), request.getUserId()
        );

        if (null == plan) {
            throw new AdvertException(SystemConstant.Error.RECORD_NOT_FOUND);
        }

        plan.setPlanStatus(CommonStatus.INVALID.getStatus());
        plan.setUpdateTime(new Date());

        planRepository.save(plan);
    }
}
